package org.gpf.listener;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.gpf.vo.OnlineUser;
/**
 * 统计在线人员列表
 * 因为在线人员列表是网站全局变量-因而实现ServletContextListener
 * 每创建一个session，向上下文中添加一个用户，每销毁一个session从上下文中移除一个用户，所以实现HttpSessionListener
 * 当向session中设置用户名的时候，我们可以通过session的属性监听器取得用户名属性，所以需要实现HttpSessionAttributeListener
 * 因为需要获得客户端的ip，ip又只有request可以获取，所以需要实现ServletRequestListener
 * @author gaopengfei
 * @date 2015-4-30 下午8:10:56
 */
public class OnlineUserListener implements HttpSessionListener,
		HttpSessionAttributeListener, ServletContextListener,
		ServletRequestListener {

	ServletContext application = null;	// 全局的上下文对象用于存放在线人员列表
	OnlineUser onlineUser = null;		// 在线用户
	HttpServletRequest request = null;	// 获取客户端IP
	List<OnlineUser> onlineUsers = null;// 存放在线用户的list
	
	@Override
	public void requestDestroyed(ServletRequestEvent event) {

	}

	/**
	 * 通过request监听器初始化request对象
	 */
	@Override
	public void requestInitialized(ServletRequestEvent event) {
		
		request = (HttpServletRequest) event.getServletRequest();
	}

	/**
	 * 容器销毁的时候移除在线人员列表
	 */
	@Override
	public void contextDestroyed(ServletContextEvent event) {
		
		application = null;
	}

	/**
	 * 容器初始化的时候实例化全局上下文对象application，并创建一个onLineUserList的ArrayList用来保存在线用户
	 */
	@Override
	public void contextInitialized(ServletContextEvent event) {
		
		application = event.getServletContext();
		// 下面的这一句相当于List<OnlineUser>onlineUserList = new ArrayList<OnlineUser>();
		application.setAttribute("onlineUserList", new ArrayList<OnlineUser>());
	}

	/**
	 * 向session中增加用户名的时候触发属性增加监听器，这时设置在线用户的各个属性并将其添加到集合中，并保存于上下文对象
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void attributeAdded(HttpSessionBindingEvent event) {

		onlineUsers = (List<OnlineUser>) application.getAttribute("onlineUserList");
		if (onlineUser!=null) {
			onlineUser.setFirstAccessTime(new Date());
			onlineUser.setSessionID(event.getSession().getId());
			onlineUser.setUsername((String) event.getValue());
			onlineUser.setIp(request.getRemoteAddr());
			onlineUsers.add(onlineUser);
		}
		application.setAttribute("onlineUserList", onlineUsers);

	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent event) {

	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent event) {

	}

	/**
	 * session创建的时候创建一个OnlineUser对象
	 */
	@Override
	public void sessionCreated(HttpSessionEvent event) {

		onlineUser = new OnlineUser();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void sessionDestroyed(HttpSessionEvent event) {

		onlineUsers = (List<OnlineUser>) application.getAttribute("onlineUserList");
		if(onlineUsers!=null&&onlineUsers.size()!=0)
			onlineUsers.remove(0);						//	session销毁时，移除第一个元素（即：最先加入的元素）
		
		application.setAttribute("onlineUserList", onlineUsers);
	}

}
